﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Animation;

namespace LogInModule.Views.Helpers
{
    public class FloatingService
    {
        private const double seconds = 2.0;

        public static readonly DependencyProperty IsChildrenFloatingProperty =
            DependencyProperty.RegisterAttached("IsChildrenFloating", typeof(bool), typeof(FloatingService),
                                                new PropertyMetadata(false, OnIsChildrenFloatingChanged));

        public static readonly DependencyProperty ProjectionMaxProperty =
            DependencyProperty.RegisterAttached("ProjectionMax", typeof(int), typeof(FloatingService),
                                                new PropertyMetadata(30));

        public static readonly DependencyProperty TranslateMaxProperty =
            DependencyProperty.RegisterAttached("TranslateMax", typeof(int), typeof(FloatingService),
                                                new PropertyMetadata(20));

        private static readonly Random random = new Random();

        public static bool GetIsChildrenFloating(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsChildrenFloatingProperty);
        }

        public static void SetIsChildrenFloating(DependencyObject obj, bool value)
        {
            obj.SetValue(IsChildrenFloatingProperty, value);
        }

        public static int GetProjectionMax(DependencyObject obj)
        {
            return (int)obj.GetValue(ProjectionMaxProperty);
        }

        public static void SetProjectionMax(DependencyObject obj, int value)
        {
            obj.SetValue(ProjectionMaxProperty, value);
        }

        public static int GetTranslateMax(DependencyObject obj)
        {
            return (int)obj.GetValue(TranslateMaxProperty);
        }

        public static void SetTranslateMax(DependencyObject obj, int value)
        {
            obj.SetValue(TranslateMaxProperty, value);
        }

        private static void OnIsChildrenFloatingChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
        {
            var panel = obj as Panel;
            if (panel != null)
            {
                if ((bool)args.NewValue)
                    panel.Loaded += PanelLoaded;
                else
                    panel.Loaded -= PanelLoaded;
            }
        }

        private static void PanelLoaded(object sender, RoutedEventArgs e)
        {
            var panel = sender as Panel;
            if (panel != null)
            {
                var projectionMax = GetProjectionMax(panel);
                var translateMax = GetTranslateMax(panel);

                foreach (UIElement child in panel.Children)
                {
                    var storyboard = new Storyboard();

                    PlaneProjection planeProjection;
                    child.EnsureProjection(out planeProjection);

                    DoubleAnimation projectionX = AnimationFactory.CreateProjectionXAnimation(planeProjection, random.Next(projectionMax), seconds);
                    DoubleAnimation projectionY = AnimationFactory.CreateProjectionYAnimation(planeProjection, random.Next(projectionMax), seconds);
                    DoubleAnimation projectionZ = AnimationFactory.CreateProjectionZAnimation(planeProjection, random.Next(projectionMax), seconds);

                    storyboard.Children.Add(projectionX);
                    storyboard.Children.Add(projectionY);
                    storyboard.Children.Add(projectionZ);

                    ScaleTransform scale;
                    TranslateTransform translate;
                    RotateTransform rotate;
                    SkewTransform skew;
                    child.EnsureTransforms(out scale, out rotate, out skew, out translate);

                    DoubleAnimation translateX = AnimationFactory.CreateTranslateXAnimation(translate, random.Next(translateMax), seconds);
                    DoubleAnimation translateY = AnimationFactory.CreateTranslateYAnimation(translate, random.Next(translateMax), seconds);

                    storyboard.Children.Add(translateX);
                    storyboard.Children.Add(translateY);

                    storyboard.Completed += (s, e1) =>
                    {
                        projectionX.To = random.Next(projectionMax);
                        projectionY.To = random.Next(projectionMax);
                        projectionZ.To = random.Next(projectionMax);
                        translateX.To = random.Next(translateMax);
                        translateY.To = random.Next(translateMax);
                        storyboard.Begin();
                    };
                    storyboard.Begin();
                }
            }
        }
    }
}
